<template>
  <div class="about">
    <!--左侧 -->
    <Row class="section-l mr-20">
      <Row class="title-top mb-10">
        <p class="title mb-10">1.操作increment or decrement显示的结果: {{ count }}</p>
        <Button class="mr-10" type="primary" @click="add(2)">increment</Button>
        <Button class="mr-10" type="error" @click="minus(1)">decrement</Button>
        <Button type="primary" @click="showTable">列表数据</Button>
      </Row>
      <Row class="title-top mb-10">
        <div class="data-json">
          <p class="title mb-10">2.typescript绑定Vue过滤器filters</p>
          <div class="mb-5">
            将首字母转化为大写:
            <label class="ml-5">{{ textToFormat | requireFilterName }}</label>
            <br />css样式将首字母转化为大写:
            <label class="capital">hello</label>
          </div>
          <div class="mb-5">
            将时间日期进行格式化:
            <label class="ml-5">{{ formatDate | requireFilterDate }}</label>
          </div>
          <div>
            自定义一个指令进行聚焦元素:
            <label class="reInput ml-5">
              <input type="text" v-focus v-model="textToFormat" />
            </label>
          </div>
        </div>
      </Row>
      <Row class="title-top">
        <h3 class="title mb-10">3.使用cropper.js制作头像/图片上传、裁剪、并发送至后端</h3>
        <div>功能演示</div>
        <div class="img-wrapper">
          <div class="img-box mr-20">
            <Avatar :src="cropImg" size="large" />
            <!--更换头像 -->
            <!--不能使用transiton，初始化渲染时才可使用,因此需要通过animation设置 -->
            <!-- <transition name="fade-transform" mode="out-in"> </transition>-->
            <div class="spin-loading active-img" @click="uploadImg">
              <Icon type="md-contact" />更换头像
            </div>
          </div>
          <div>
            <!-- 1.一个用于获取上传文件的input，type="file"，并且监听onchange事件  -->
            <input
              ref="imgRef"
              class="imgForm"
              type="file"
              accept="image/*"
              id="imgReader"
              @change="loadingImg"
            />
            <!--2.一个用来使用cropper.js覆盖的img -->
            <div class="mainBox">
              <div class="leftBox mr-30">
                <img id="cropImg" />
              </div>
              <div class="rightBox">
                <!--3.两个用来预览div -->
                <div class="previewText">裁剪的内容</div>
                <div class="previewBox"></div>
                <div class="previewBoxRound"></div>
              </div>
            </div>
          </div>
        </div>
      </Row>
      <Row class="title-top mt-20">
        <h3 class="title mb-10">4.阿里云上传图片</h3>
        <Form
          class="addForm"
          ref="addForm"
          :model="addForm"
          :rules="formValidate"
          :label-width="120"
        >
          <Form-item label="类型" prop="type">
            <Select v-model="addForm.type" clearable>
              <Option v-for="item in typeList" :key="item.id" :value="item.id">{{
                item.name
              }}</Option>
            </Select>
          </Form-item>
          <Form-item label="名称" prop="name">
            <Input type="text" v-model="addForm.name" placeholder="请输入名称" :maxlength="21" />
          </Form-item>
          <Form-item label="appid" prop="appId">
            <Input
              type="text"
              v-model="addForm.appId"
              placeholder="请输入appId"
              :maxlength="31"
              :disabled="addForm.type == 'edit'"
            />
          </Form-item>
          <Form-item label="appsecret" prop="appSecret">
            <Input
              type="text"
              v-model="addForm.appSecret"
              placeholder="请输入appSecret"
              :maxlength="31"
            />
          </Form-item>
          <FormItem label="欢迎语正文">
            <Input
              v-model="addForm.welcomeContent"
              :maxlength="100"
              type="textarea"
              :rows="4"
              placeholder="请输入..."
            ></Input>
            <span class="form-welcome-len">{{ welconmeLen }}/100</span>
            <Row>
              <Col span="24" class="desc-text">
                <div>欢迎语正文最多显示100个汉字，为空则不显示</div>
              </Col>
            </Row>
          </FormItem>
          <FormItem label="背景图设置">
            <Row>
              <Col span="24" class="desc-text">
                <div>
                  可以保存 5 张背景图片以供切换，请上传尺寸为1920*1200的.png/.jpeg/.jpg格式图片
                </div>
              </Col>
            </Row>
            <Row>
              <Col class="span">
                <file-upload
                  :list.sync="addForm.loginBackgroundList"
                  v-model="appIcons"
                  title="点击上传背景图"
                  iconType="md-add"
                  :max="5"
                  max-file-size="10mb"
                  extensions="jpg,png,jpeg"
                  policy-url="/wec-smmp-sconf/potal/oss/getImportPolicy"
                  oss-file-url="/potal/oss/previewAttachment"
                  :oss-file-url-setting="{ filePathKey: 'ossKey' }"
                  :params="{ fileType: 5 }"
                  @file-uploaded="fileUploaded"
                  @on-del="delIconItem"
                  @on-select="selectBgImg"
                  style="width:936px;"
                ></file-upload>
                {{ addForm.loginBackgroundList }}
                <Input type="hidden" v-model="addForm.loginBackgroundList" />
              </Col>
            </Row>
          </FormItem>
          <FormItem label="附件" props="uploadFiles">
            <!-- :ossparams="{schoolId:'1018397330230334'}"
            :params="{schoolId:'1018397330230334',appId:''}"-->
            <file-upload
              :value="addForm.uploadFiles"
              title="上传附件"
              :max="3"
              description="仅支持20M以内的zip、pdf文件"
              max-file-size="20mb"
              extensions="zip,pdf"
              policy-url="/wec-msg-mngt/msgmngt/getImportPolicy"
              oss-file-url="/wec-msg-mngt/msgmngt/previewAttachment"
              :oss-file-url-setting="{ filePathKey: 'ossKey' }"
              :readonly="false"
              :params="{ fileType: 2 }"
              empty-text="没有附件"
              @file-uploaded="fileUploaded"
              @on-del="fileDel"
              style="width: 900px;"
            ></file-upload>
          </FormItem>
          <FormItem>
            <Button type="primary" class="mr-10">提交</Button>
            <Button>重置</Button>
          </FormItem>
        </Form>
      </Row>
    </Row>
    <Row class="mb-20">
      <div class="title">使用 obj.getBoundingClientRect().top 实现滚动吸顶</div>
      <!--吸顶组件 -->
      <view-sticky></view-sticky>
    </Row>

    <!--弹出框 -->
    <base-modal
      v-model="confirmModel"
      title="展示列表"
      width="600"
      type="info"
      okText="展示"
      @on-ok="ok"
      @on-cancel="confirmModel = false"
      simple
    >
      <Input
        class="mb-10"
        v-model.trim="userInfo.keyword"
        @on-enter="getTableList()"
        placeholder="输入姓名、工号、学号"
        search
        clearable
      />
      <Table
        ref="table"
        class="mt-10"
        height="400"
        @on-selection-change="selectChange"
        border
        :columns="groupColumns"
        :data="tableData"
      ></Table>
      <Page
        class="mt-10"
        :total="totalSize"
        show-sizer
        @on-change="pageNumChange"
        @on-page-size-change="pageSizeChange"
        show-total
      />
    </base-modal>
    <base-modal
      title="确认选择"
      type="warning"
      :value="selectBgConfirm"
      @on-ok="onSelect"
      @on-cancel="selectBgConfirm = false"
      :mask-closable="false"
      okText="选择"
      simple
    >
      <label>确认选择该图片作为背景图吗？</label>
    </base-modal>
  </div>
</template>
<script lang="ts">
import { Component, Vue, Prop, Mixins, Watch } from "vue-property-decorator";
import { State, Getter, Mutation, Action } from "vuex-class";
import { TableColumn, Form } from "iview";
import { listData, userInfo, AliForm, ImageData } from "@/store/interface";
import BaseModal from "@components/iv-modal/BaseModal.vue";
import { Tools } from "@/model/tools.ts";
import FileUpload from "@components/file-upload/fileUpload.vue";
import ViewSticky from "@views/ViewSticky.vue";
import { ImgMixin } from "@mixins/index.ts";
import { cropperUpload } from "@/api/service.js";
import { requireFilterDate, requireFilterName } from "@/filters/register-filter.ts";

//引入Cropper.js
import "cropperjs/dist/cropper.css";
import Cropper from "cropperjs";
let CROPPER; //创建一个cropper的全局对象

@Component({
  directives: {
    // 自定义指令
    focus
  },
  components: {
    BaseModal,
    FileUpload,
    ViewSticky
  },
  mixins: [ImgMixin],
  filters: {
    //局部过滤器
    requireFilterDate,
    requireFilterName
  }
})
export default class BaseForm extends Tools {
  // 易错点 $refs: 确实! 引入 Form from 'iview'
  public $refs!: {
    table: any;
    imgRef: any;
    addForm: Form;
    imgForm: Form;
  };
  //过滤器
  private textToFormat: string = "hello world";
  private formatDate: string = "20160102";
  private confirmModel: boolean = false;
  private tableData: Array<listData> = []; // data属性初始化
  private totalSize: number = 0;
  private delBgConfirm: boolean = false;
  private delItemBgParams: Object = {};
  private selectBgConfirm: boolean = false;
  private selectedParams: Object = {};
  // 初始化接口值
  private userInfo: userInfo = {
    pageNumber: 1,
    pageSize: 10,
    keyword: "",
    groupId: "9b00fb60-b6de-489b-ad66-85affff3794b",
    purpose: "2",
    selectedIds: []
  };
  private formData: AliForm = {
    welcomeContent: "",
    loginBackgroundList: [],
    uploadFiles: [] //上传图片集合
  };
  //更换头像
  private imgForm: any = {};

  //store中获取
  @Getter("count") count!: any;
  // 第一种写法
  // @Mutation
  // private INCREMENT!: (count: number) => any; //返回方法 () => void 与 Function等效

  // 推荐的写法
  @Mutation("INCREMENT")
  private increment!: (count: number) => any;

  // 第二种写法
  @Mutation private DECREMENT!: Function;

  @Action
  private MANAGER_USER_QUERY!: (param: userInfo) => Promise<listData>;
  @Action
  private QUERY_BASIC_INFO!: () => Promise<listData>;

  //================计算属性========================
  private get appIcons() {
    let loginBackgroundList = this.addForm.loginBackgroundList;
    if (loginBackgroundList != undefined && loginBackgroundList.length > 0) {
      loginBackgroundList.filter(item => {
        item.url = item.imgUrl;
        return item;
      });
      return loginBackgroundList;
    } else {
      return [];
    }
  }

  private get cropImg() {
    return require("../../assets/img/avatar-icon.jpg");
  }

  private get welconmeLen() {
    return this.isNull(this.addForm.welcomeContent) ? this.addForm.welcomeContent.length : 0;
  }

  private get groupColumns(): Array<TableColumn> {
    return [
      {
        type: "selection",
        width: 60,
        align: "center"
      },
      {
        title: "工号/学号",
        key: "userAccount"
      },
      {
        title: "姓名",
        key: "userName",
        align: "center"
      },

      {
        title: "性别",
        key: "userGender",
        align: "center"
      },
      {
        title: "部门/院系",
        key: "userDepartment",
        align: "center"
      },
      {
        title: "角色",
        key: "userType",
        align: "center"
      }
    ];
  }

  /**
   * 类型
   */
  private get typeList() {
    return [
      {
        id: "1",
        name: "服务号"
      },
      {
        id: "2",
        name: "企业号"
      }
    ];
  }
  private get formValidate() {
    return {
      type: [
        {
          required: true,
          message: "请选择类型"
        }
      ],
      name: [
        {
          required: true,
          message: "请选择类型",
          trigger: "blur"
        },
        {
          max: 20,
          message: "名称长度不能超过20"
        }
      ],
      appId: [
        {
          required: true,
          message: "请输入appId"
        },
        {
          max: 30,
          message: "appId长度不能超过30"
        },
        {
          pattern: /^[0-9a-zA-Z]+$/,
          message: "仅允许数字与字母"
        }
      ],
      appSecret: [
        {
          required: true,
          message: "请输入appSecret"
        },
        {
          max: 30,
          message: "appSecret长度不能超过30"
        },
        {
          pattern: /^[0-9a-zA-Z]+$/,
          message: "仅允许数字与字母"
        }
      ],
      uploadFiles: [
        {
          required: true,
          message: "请选择文件"
        }
      ]
    };
  }

  /**
   * 提交数据
   */
  private get addForm() {
    return this.formData;
  }

  private set addForm(value) {}

  //==========开始methods方法============
  private uploadImg() {
    let dom: any = document.querySelector("#imgReader");
    dom.click();
    //再次上传不同图片的时候，还是出现原来的图片，只需要在上传文件的时候，对之前存在的CROPPER进行摧毁就可以了
    if (CROPPER) {
      CROPPER.destroy();
    }
  }

  private loadingImg(eve) {
    //读取上传文件
    let reader = new FileReader();
    if (eve.target.files[0]) {
      //readAsDataURL方法可以将File对象转化为data:URL格式的字符串（base64编码）
      reader.readAsDataURL(eve.target.files[0]);
      reader.onload = e => {
        let dataURL = reader.result;
        //将img的src改为刚上传的文件的转换格式
        let cropImg: any = document.querySelector("#cropImg");
        console.log(cropImg);
        cropImg.src = dataURL;
        //获取img对应DOM
        const image: any = document.getElementById("cropImg");
        //创建cropper实例
        let imageData: ImageData = {
          aspectRatio: 16 / 16, //固定裁剪框的比例（横/竖）,此处16/16则固定为正方形
          viewMode: 0, //容器最小的宽度
          minContainerWidth: 100,
          minContainerHeight: 100,
          dragMode: "move", //设置裁剪框为可以移动
          preview: [
            document.querySelector(".previewBox"), //设置我们需要添加实时预览的地方
            document.querySelector(".previewBoxRound")
          ]
        };
        CROPPER = new Cropper(image, imageData); //第一个参数作用：用于显示裁剪功能
      };
    }
  }
  private getData() {
    //getCroppedCanvas方法可以将裁剪区域的数据转换成canvas数据
    CROPPER.getCroppedCanvas({
      maxWidth: 4096,
      maxHeight: 4096,
      fillColor: "#fff",
      imageSmoothingEnabled: true,
      imageSmoothingQuality: "high"
    }).toBlob(async blob => {
      //然后调用浏览器原生的toBlob方法将canvas数据转换成blob数据
      //之后就可以愉快的将blob数据发送至后端啦，可根据自己情况进行发送，我这里用的是axios
      const formData = new FormData();
      // 第三个参数为文件名，可选填.
      formData.append("croppedImage", blob /*, 'example.png' */);
      let config = {
        headers: { "Content-Type": "multipart/form-data" }
      };
      const [err, data] = await cropperUpload(config);
    });
  }

  /**
   * 上传图片
   */
  private fileUploaded(res, res2) {
    this.commonFileUpload(res, res2, "images");
  }
  //公共方法
  private commonFileUpload(res, res2, type) {
    //上传到服务器
  }
  private delIconItem(params) {
    this.delBgConfirm = true;
    this.delItemBgParams = params;
  }
  private selectBgImg(params) {
    this.selectBgConfirm = true;
    this.selectedParams = params;
  }

  private onSelect() {}

  /**
   * 删除图片
   */
  private fileDel() {}

  private add(count: number): void {
    //this.INCREMENT(count);
    this.increment(count);
  }

  private minus(count: number): void {
    this.DECREMENT(count);
  }

  /**
   * 获取列表数据
   */
  private showTable() {
    // this.loading(true); // 引入tools.ts中的loading()方法更新mutations
    this.confirmModel = true;
    this.getTableList();
  }

  getTableList(obj: userInfo = this.userInfo) {
    this.MANAGER_USER_QUERY(obj).then(res => {
      if (res.rows != null) {
        this.commLoading(false);
        this.tableData = res.rows;
        this.totalSize = res.totalSize;
      } else {
        this.tableData = [];
        this.totalSize = 0;
      }
    });
  }

  private isNull(value) {
    if (typeof value != "undefined" && value != null) {
      return true;
    } else {
      return false;
    }
  }

  /**
   * 弹出层
   */
  private ok(): void {}

  private selectChange() {}

  private pageNumChange(num: number): void {
    this.userInfo.pageNumber = num;
    this.getTableList();
  }

  private pageSizeChange(num: number): void {
    this.userInfo.pageSize = num;
    this.getTableList();
  }

  mounted() {
    // console.log("输出table的refs", this.$refs.table);
    this.QUERY_BASIC_INFO().then(res => {
      this.formData = JSON.parse(JSON.stringify(res)); //深层拷贝
    });
  }

  /**
   * Watch监听属性变化
   */
  @Watch("textToFormat", { immediate: true, deep: true })
  private onChildChanged(val: string, oldVal: string) {
    console.log("watch new name=" + val);
  }
}
</script>
<style lang="stylus" scoped>
.about {
  display: flex
  flex-flow: row nowrap
  .section-l {
    flex-grow: 1
  }
  .addForm {
    width: 400px
  }
  .desc-text {
    color: rgb(148, 148, 148)
    line-height: 28px
  }
  .form-welcome-len {
    position: absolute
    bottom: 22px
    right: 10px
    color: #949494
    font-size: 12px
  }
  .capital {
    text-transform: capitalize // 首字母大写
  }
  .reInput input {
    caret-color: red // 修改input输入框中光标的颜色不改变字体的颜色
  }
  .img-wrapper {
    display: flex
    height: 280px
  }
  .imgForm {
    display: none
    width: 180px
    height: 180px
    box-sizing: border-box
    position: relative
  }
  // 预览图片展示的效果
  .previewBox, .previewBoxRound {
    box-shadow: 0 0 5px #adadad
    width: 100px
    height: 100px
    margin-top: 10px
    overflow: hidden /* 这个超出设置为隐藏很重要，否则就会整个显示出来了 */
  }
  .previewBoxRound {
    border-radius: 50% /* 设置为圆形 */
  }
  #cropImg {
    height: 150px
    width: 150px
    box-shadow: 0 0 5px #adadad
  }
  .mainBox {
    display: flex
  }
  .img-box {
    box-sizing: border-box
    position: relative
    display: flex
    align-items: center
    justify-content: center
    width: 75px
    height: 75px
    line-height: 75px
    border-radius: 50%
    &:hover {
      border: 1px solid #2D8CF0
      cursor: pointer
      .active-img {
        display: block
      }
    }
    .active-img {
      display: none
      position: absolute
      left: 0
      top: 0
      width: 100%
      height: 100%
      background: #E9E9E9
      border-radius: 50%
      overflow: hidden
      text-align: center
      font-size: 12px
    }
  }
  >>>.ivu-avatar-large {
    width: 70px
    height: 70px
    line-height: 70px
    border-radius: 35px
  }
}
</style>
